From b9b507266888a7e94cb6ef10f3e9bdea834f86d0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timm=20B=C3=A4der?= Date: Sat, 13 Jul 2019 17:35:59 +0200 Subject: [PATCH] gl renderer: Fix opacity nodes with overlapping child nodes --- gsk/gl/gskglrenderer.c | 45 ++++++++++++++++-- .../compare/opacity-overlapping-children.node | 13 +++++ .../compare/opacity-overlapping-children.png | Bin 0 -> 512 bytes testsuite/gsk/meson.build | 3 +- 4 files changed, 56 insertions(+), 5 deletions(-) create mode 100644 testsuite/gsk/compare/opacity-overlapping-children.node create mode 100644 testsuite/gsk/compare/opacity-overlapping-children.png diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 46c9e64c1c..65fdc0c13e 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -1015,12 +1015,49 @@ render_opacity_node (GskGLRenderer *self, GskRenderNode *node, RenderOpBuilder *builder) { + GskRenderNode *child = gsk_opacity_node_get_child (node); + const float opacity = gsk_opacity_node_get_opacity (node); float prev_opacity; - prev_opacity = ops_set_opacity (builder, - builder->current_opacity * gsk_opacity_node_get_opacity (node)); + if (gsk_render_node_get_node_type (child) == GSK_CONTAINER_NODE) + { + const float min_x = builder->dx + node->bounds.origin.x; + const float min_y = builder->dy + node->bounds.origin.y; + const float max_x = min_x + node->bounds.size.width; + const float max_y = min_y + node->bounds.size.height; + gboolean is_offscreen; + TextureRegion region; + + /* The semantics of an opacity node mandate that when, e.g., two color nodes overlap, + * there may not be any blending between them */ + add_offscreen_ops (self, builder, &child->bounds, + child, + ®ion, &is_offscreen, + FORCE_OFFSCREEN | RESET_OPACITY | RESET_CLIP); - gsk_gl_renderer_add_render_ops (self, gsk_opacity_node_get_child (node), builder); + prev_opacity = ops_set_opacity (builder, + builder->current_opacity * opacity); + + ops_set_program (builder, &self->blit_program); + ops_set_texture (builder, region.texture_id); + + ops_draw (builder, (GskQuadVertex[GL_N_VERTICES]) { + { { min_x, min_y }, { region.x, region.y2 }, }, + { { min_x, max_y }, { region.x, region.y }, }, + { { max_x, min_y }, { region.x2, region.y2 }, }, + + { { max_x, max_y }, { region.x2, region.y }, }, + { { min_x, max_y }, { region.x, region.y }, }, + { { max_x, min_y }, { region.x2, region.y2 }, }, + }); + } + else + { + prev_opacity = ops_set_opacity (builder, + builder->current_opacity * opacity); + + gsk_gl_renderer_add_render_ops (self, child, builder); + } ops_set_opacity (builder, prev_opacity); } @@ -1290,7 +1327,7 @@ render_rounded_clip_node (GskGLRenderer *self, { { min_x, min_y }, { 0, 1 }, }, { { min_x, max_y }, { 0, 0 }, }, { { max_x, min_y }, { 1, 1 }, }, - + { { max_x, max_y }, { 1, 0 }, }, { { min_x, max_y }, { 0, 0 }, }, { { max_x, min_y }, { 1, 1 }, }, diff --git a/testsuite/gsk/compare/opacity-overlapping-children.node b/testsuite/gsk/compare/opacity-overlapping-children.node new file mode 100644 index 0000000000..0267b594e4 --- /dev/null +++ b/testsuite/gsk/compare/opacity-overlapping-children.node @@ -0,0 +1,13 @@ +opacity { + opacity: 0.4; + child: container { + color { + color: blue; + bounds: 0 0 100 100; + } + color { + color: red; + bounds: 50 50 100 100; + } + } +} \ No newline at end of file diff --git a/testsuite/gsk/compare/opacity-overlapping-children.png b/testsuite/gsk/compare/opacity-overlapping-children.png new file mode 100644 index 0000000000000000000000000000000000000000..ef6784028a993ea845deb25204317726dcbfc7db GIT binary patch literal 512 zcmeAS@N?(olHy`uVBq!ia0vp^(?FPm4M^HB7Cr(}Y)RhkE)4%caKYZ?lNlHow|crb zhE&XXd-otOv!Vct;|7`6tWQ%4g|=8MT*dM1;;r}R46hkiO#ErRH=+IfOU65%5h^XN zPV^@pRaYI*%RX~ixNPU6$7{O>!UIKaA$*S%2L9 S?{pd%r3{{~elF{r5}E+1zPS(p literal 0 HcmV?d00001 diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index 2208c1a6d6..574f9368ca 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -58,7 +58,8 @@ compare_render_tests = [ 'texture-url', 'color-matrix-identity', 'clip-nested1', - 'scale-up-down' + 'scale-up-down', + 'opacity-overlapping-children', ] renderers = [ -- 2.30.2